using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace SocketClient
{

    public class StoragePoint
    {
        public StoragePoint(StoragePointType spType,string name)
        {
            this._storagePointType = spType;
            this._name = name;
        }

#region StoragePointType
        /// <summary>
        /// 
        /// </summary>
        public StoragePointType StoragePointType
        {
            get
            {
                return _storagePointType;
            }
        } private StoragePointType _storagePointType;
#endregion //StoragePointType

        /// <summary>
        /// 
        /// </summary>
        public string Name
        {
            get { return _name; }
        } private string _name;

        public StoragePoint In
        {
            get { return _in; }
            set
            {
                _in = value;
                value._out= this;
            }
        } private StoragePoint _in = null;


        public StoragePoint Out
        {
            get { return _out; }
            set
            {
                _out = value;
                value._in = this;
            }
        } private StoragePoint _out;

        public void AddToEnd(StoragePoint sp)
        {
            if (sp == null)
            {
                throw new ArgumentNullException("sp");
            }

            StoragePoint current = this;
            while (current._out != null)
            {
                current = current._out;
            }
            current._out = sp;
            //sp.In = current;
        }

        public override string ToString()
        {
            string s = string.Empty;
            s = this.Name;
            StoragePoint current = _out;
            while (current != null)
            {
                s += Strings.RightArrow + current.Name;
                current = current._out;
            }
            return s;
        }

        internal StoragePoint Find(StoragePointType storagePointType)
        {
            StoragePoint current = this;
            while (current != null && 
                    current.StoragePointType != storagePointType)
            {
                current = current.Out;
            }
            return current;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        internal object[] ToArray()
        {
            // 0 1 2 3 4
            // s - c - com
            //
            string[] r = new string[5];
            StoragePoint current = this;
            while (current != null)
            {
                int index = GetIndex(current.StoragePointType);
                r[index] = current.Name;
                StoragePoint next = current.Out;

                if (next != null)
                {
                    if (next.StoragePointType > current.StoragePointType)
                    {
                        r[index - 1] = Strings.LeftArrow;
                    }
                    else if (next.StoragePointType < current.StoragePointType)
                    {
                        r[index + 1] = Strings.RightArrow;
                    }
                    else
                    {
                        throw new InvalidProgramException("StoragePoint type == with out");
                    }
                }

                current = current.Out;
            }
            return r;
        }

        private int GetIndex( StoragePointType spType)
        {
            Hashtable hs = new Hashtable();
            hs[StoragePointType.S] = 0;
            hs[StoragePointType.C] = 2;
            hs[StoragePointType.Com] = 4;

            return (int)hs[spType];
        }

        public DataDirection EnsureDirection()
        {
            if (this.Out != null)
            {
                return this.StoragePointType > this.Out.StoragePointType ? 
                    DataDirection.Out  : DataDirection.In;
            }
            else
            {
                return DataDirection.Unknown;
            }
        }
    }
}
